<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
import { enableStatusOptions } from '@/constants/business';
import { fetchEditUser, fetchGetAllRoles, fetchSaveUser } from '@/service/api';

defineOptions({
  name: 'UserOperateModal'
});
interface Props {
  operateType: NaiveUI.TableOperateType;
  rowData?: Api.SystemManage.User | null;
}
interface Emits {
  (e: 'submitted'): void;
}
const props = defineProps<Props>();
const visible = defineModel<boolean>('visible', { default: false });
const emit = defineEmits<Emits>();
const add = computed(() => props.operateType === 'add');
const title = computed(() => {
  const titles: Record<NaiveUI.TableOperateType, string> = {
    add: $t('page.manage.user.addUser'),
    edit: $t('page.manage.user.editUser')
  };
  return titles[props.operateType];
});
type Model = Api.SystemManage.UserEdit & { id: number | null };
const model: Model = reactive(createDefaultModel());
const roleOptions = ref<CommonType.Option<number>[]>([]);

type RuleKey = Extract<keyof Model, 'account' | 'password' | 'realName'>;
const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule, formRules } = useFormRules();
const rules: Record<RuleKey, App.Global.FormRule[]> = {
  account: [defaultRequiredRule],
  password: formRules.pwd,
  realName: [defaultRequiredRule]
  // phone: formRules.phone,
  // email: formRules.email
};
function createDefaultModel(): Model {
  return {
    id: null,
    account: '',
    password: '',
    nickName: '',
    realName: '',
    email: '',
    phone: '',
    status: '1',
    roleIds: []
  };
}

function onlyAllowAlphaNumber(val: string): boolean {
  console.log(val);
  return !val || /^[a-zA-Z0-9]+$/.test(val);
}

async function getRoleOptions() {
  const { error, data } = await fetchGetAllRoles();
  if (!error) {
    const options = data?.map(role => ({
      label: role.name,
      value: role.id
    }));

    // const userRoleOptions = model.roleIds.map(roleId => ({
    //   label: roleId,
    //   value: roleId
    // }));

    roleOptions.value = options;
  }
}

async function handleSubmit() {
  await validate();

  const func = add.value ? fetchSaveUser : fetchEditUser;
  const { error, data } = await func(model);
  if (!error && data) {
    window.$message?.success(add.value ? $t('common.addSuccess') : $t('common.updateSuccess'));
    emit('submitted');
    closeDrawer();
  }
}
function closeDrawer() {
  visible.value = false;
}
function handleInitModel() {
  Object.assign(model, createDefaultModel());

  if (props.operateType === 'edit') {
    Object.assign(model, props.rowData);
  } else {
    Object.assign(model, { id: null });
  }
}
watch(visible, () => {
  if (visible.value) {
    handleInitModel();
    restoreValidation();
    getRoleOptions();
  }
});
</script>

<template>
  <!--不添加card，弹框不显示-->
  <NModal v-model:show="visible" :title="title" preset="card" class="w-800px">
    <NScrollbar>
      <NForm
        ref="formRef"
        :model="model"
        :rules="rules"
        :mask-closable="true"
        label-placement="left"
        label-width="auto"
        require-mark-placement="right-hanging"
      >
        <NGrid responsive="screen" item-responsive>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.account')" path="account">
            <NInput
              v-model:value="model.account"
              maxlength="20"
              minlength="2"
              :disabled="!add"
              :placeholder="$t('page.manage.user.form.account')"
              :allow-input="onlyAllowAlphaNumber"
            />
          </NFormItemGi>
          <NFormItemGi v-if="add" span="24 m:12" :label="$t('page.manage.user.password')" path="password">
            <NInput
              v-model:value="model.password"
              :placeholder="$t('page.manage.user.form.password')"
              type="password"
              show-password-on="click"
            />
          </NFormItemGi>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.realName')" path="realName">
            <NInput v-model:value="model.realName" :placeholder="$t('page.manage.user.form.realName')" />
          </NFormItemGi>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.nickName')" path="nickName">
            <NInput v-model:value="model.nickName" :placeholder="$t('page.manage.user.form.nickName')" />
          </NFormItemGi>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.email')" path="email">
            <NInput v-model:value="model.email" :placeholder="$t('page.manage.user.form.email')" />
          </NFormItemGi>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.phone')" path="phone">
            <NInput v-model:value="model.phone" :placeholder="$t('page.manage.user.form.phone')" />
          </NFormItemGi>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.status')" path="status">
            <NRadioGroup v-model:value="model.status">
              <NRadio
                v-for="item in enableStatusOptions"
                :key="item.value"
                :value="item.value"
                :label="$t(item.label)"
              />
            </NRadioGroup>
          </NFormItemGi>
          <NFormItemGi span="24 m:12" :label="$t('page.manage.user.userRole')" path="roleIds">
            <NSelect
              v-model:value="model.roleIds"
              :options="roleOptions"
              multiple
              :placeholder="$t('page.manage.user.form.userRole')"
            />
          </NFormItemGi>
        </NGrid>
      </NForm>
    </NScrollbar>
    <template #footer>
      <NSpace justify="end">
        <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
        <NButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style scoped></style>
